
(def (noteToPc [pitch-integer? i])
  (modulo i 12))

'(TEST
 > (X 1 9)
 ;; not 8
 )


(def r0 (.map '(3 1 9 5 4 6 8 7 12 10 11 2) dec-function))
(def ri0 (.map '(3 5 9 1 2 12 10 11 6 8 7 4) dec-function))

(def (invertRow [twelve-tone-row? r])
  "revert diffs"
  (letv ((p0 is) (chord->intervals r))
        (map noteToPc
             (intervals->chord p0 (map - is)))))

(TEST
  > (equal? (invertRow r0) ri0)
  #t)

(def (random-twelve-tone-row) -> twelve-tone-row?
     (=> (iota 12)
         (.map (lambda (v) (cons (random-float) v)))
         (sort (on car <))
         (.map cdr)))

(def (twelve-tone-row->intervals [twelve-tone-row? v])
     (chord->intervals v))

(def (transposeRow c i)
     (map (lambda (v) (noteToPc (+ v i))) c))

(def (twelveToneMatrix.1 [twelve-tone-row? r0])
  (let (ri (invertRow r0))
    ;; ri = pitches
    (map (lambda (v)
           (transposeRow ri (- v (first r0))))
         r0)))

(def (twelveToneMatrix [twelve-tone-row? r0])
  (let (ri (invertRow r0))
    ;; ri = pitches
    (map (lambda (v)
           (transposeRow r0 (- v (first ri))))
         ri)))

(def. (list.inc v) (.map v inc-function))

(TEST
 > (equal? ((flip cons) 'a '())
           (cons '() 'a))
 #t)

(def. (lists.inc v) (.map v .inc))

(TEST
 > (=> (twelveToneMatrix r0)
       .inc)
 ((3 1 9 5 4 6 8 7 12 10 11 2)
  (5 3 11 7 6 8 10 9 2 12 1 4)
  (9 7 3 11 10 12 2 1 6 4 5 8)
  (1 11 7 3 2 4 6 5 10 8 9 12)
  (2 12 8 4 3 5 7 6 11 9 10 1)
  (12 10 6 2 1 3 5 4 9 7 8 11)
  (10 8 4 12 11 1 3 2 7 5 6 9)
  (11 9 5 1 12 2 4 3 8 6 7 10)
  (6 4 12 8 7 9 11 10 3 1 2 5)
  (8 6 2 10 9 11 1 12 5 3 4 7)
  (7 5 1 9 8 10 12 11 4 2 3 6)
  (4 2 10 6 5 7 9 8 1 11 12 3)))


(TEST
 ;; Elm examples
 > (def t (=>* .list twelveToneMatrix))
 > (t '[0 1 2 3 4 5 6 7 8 9 10 11])
 ((0 1 2 3 4 5 6 7 8 9 10 11)
  (11 0 1 2 3 4 5 6 7 8 9 10)
  (10 11 0 1 2 3 4 5 6 7 8 9)
  (9 10 11 0 1 2 3 4 5 6 7 8)
  (8 9 10 11 0 1 2 3 4 5 6 7)
  (7 8 9 10 11 0 1 2 3 4 5 6)
  (6 7 8 9 10 11 0 1 2 3 4 5)
  (5 6 7 8 9 10 11 0 1 2 3 4)
  (4 5 6 7 8 9 10 11 0 1 2 3)
  (3 4 5 6 7 8 9 10 11 0 1 2)
  (2 3 4 5 6 7 8 9 10 11 0 1)
  (1 2 3 4 5 6 7 8 9 10 11 0))
 > (t '[1 0 2 3 4 5 6 7 8 9 11 10])
 ((1 0 2 3 4 5 6 7 8 9 11 10)
  (2 1 3 4 5 6 7 8 9 10 0 11)
  (0 11 1 2 3 4 5 6 7 8 10 9)
  (11 10 0 1 2 3 4 5 6 7 9 8)
  (10 9 11 0 1 2 3 4 5 6 8 7)
  (9 8 10 11 0 1 2 3 4 5 7 6)
  (8 7 9 10 11 0 1 2 3 4 6 5)
  (7 6 8 9 10 11 0 1 2 3 5 4)
  (6 5 7 8 9 10 11 0 1 2 4 3)
  (5 4 6 7 8 9 10 11 0 1 3 2)
  (3 2 4 5 6 7 8 9 10 11 1 0)
  (4 3 5 6 7 8 9 10 11 0 2 1)))


'(def (transpose ))
